# 系统管理相关模型
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import json


class SystemLog(models.Model):
    """系统操作日志模型"""
    LOG_LEVEL_CHOICES = [
        ('DEBUG', '调试'),
        ('INFO', '信息'),
        ('WARNING', '警告'),
        ('ERROR', '错误'),
        ('CRITICAL', '严重'),
    ]
    
    MODULE_CHOICES = [
        ('auth', '用户认证'),
        ('asset', '资产管理'),
        ('inventory', '库存管理'),
        ('maintenance', '维修管理'),
        ('borrow', '借用管理'),
        ('report', '报表管理'),
        ('system', '系统管理'),
    ]
    
    level = models.CharField(max_length=10, choices=LOG_LEVEL_CHOICES, verbose_name="日志级别")
    module = models.CharField(max_length=20, choices=MODULE_CHOICES, verbose_name="模块")
    action = models.CharField(max_length=100, verbose_name="操作")
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="操作用户")
    ip_address = models.GenericIPAddressField(blank=True, null=True, verbose_name="IP地址")
    user_agent = models.TextField(blank=True, verbose_name="用户代理")
    
    # 详细信息
    message = models.TextField(verbose_name="日志消息")
    details = models.JSONField(blank=True, null=True, verbose_name="详细信息")
    
    # 时间信息
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    
    class Meta:
        verbose_name = "系统日志"
        verbose_name_plural = "系统日志"
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['level', '-created_at']),
            models.Index(fields=['module', '-created_at']),
            models.Index(fields=['user', '-created_at']),
        ]
    
    def __str__(self):
        return f"[{self.level}] {self.module} - {self.action}"
    
    @classmethod
    def log(cls, level, module, action, message, user=None, request=None, details=None):
        """记录系统日志"""
        log_data = {
            'level': level,
            'module': module,
            'action': action,
            'message': message,
            'user': user,
            'details': details,
        }
        
        if request:
            log_data['ip_address'] = cls.get_client_ip(request)
            log_data['user_agent'] = request.META.get('HTTP_USER_AGENT', '')
        
        return cls.objects.create(**log_data)
    
    @staticmethod
    def get_client_ip(request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip


class SystemParameter(models.Model):
    """系统参数配置模型"""
    PARAM_TYPE_CHOICES = [
        ('string', '字符串'),
        ('integer', '整数'),
        ('float', '浮点数'),
        ('boolean', '布尔值'),
        ('json', 'JSON'),
        ('text', '文本'),
    ]
    
    key = models.CharField(max_length=100, unique=True, verbose_name="参数键")
    name = models.CharField(max_length=200, verbose_name="参数名称")
    value = models.TextField(verbose_name="参数值")
    param_type = models.CharField(max_length=20, choices=PARAM_TYPE_CHOICES, default='string', verbose_name="参数类型")
    description = models.TextField(blank=True, verbose_name="参数描述")
    
    # 分组信息
    group = models.CharField(max_length=50, verbose_name="参数分组")
    sort_order = models.IntegerField(default=0, verbose_name="排序")
    
    # 验证规则
    validation_rule = models.TextField(blank=True, verbose_name="验证规则")
    default_value = models.TextField(blank=True, verbose_name="默认值")
    
    # 状态信息
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    is_readonly = models.BooleanField(default=False, verbose_name="是否只读")
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    updated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="更新人")
    
    class Meta:
        verbose_name = "系统参数"
        verbose_name_plural = "系统参数"
        ordering = ['group', 'sort_order', 'name']
    
    def __str__(self):
        return f"{self.name} ({self.key})"
    
    def get_typed_value(self):
        """获取类型化的参数值"""
        if self.param_type == 'integer':
            return int(self.value)
        elif self.param_type == 'float':
            return float(self.value)
        elif self.param_type == 'boolean':
            return self.value.lower() in ('true', '1', 'yes', 'on')
        elif self.param_type == 'json':
            return json.loads(self.value)
        else:
            return self.value
    
    def set_typed_value(self, value):
        """设置类型化的参数值"""
        if self.param_type == 'json':
            self.value = json.dumps(value, ensure_ascii=False)
        else:
            self.value = str(value)
    
    @classmethod
    def get_param(cls, key, default=None):
        """获取参数值"""
        try:
            param = cls.objects.get(key=key, is_active=True)
            return param.get_typed_value()
        except cls.DoesNotExist:
            return default
    
    @classmethod
    def set_param(cls, key, value, user=None):
        """设置参数值"""
        try:
            param = cls.objects.get(key=key)
            param.set_typed_value(value)
            param.updated_by = user
            param.save()
            return param
        except cls.DoesNotExist:
            return None


class DataBackup(models.Model):
    """数据备份记录模型"""
    BACKUP_TYPE_CHOICES = [
        ('full', '完整备份'),
        ('incremental', '增量备份'),
        ('manual', '手动备份'),
    ]
    
    BACKUP_STATUS_CHOICES = [
        ('pending', '待执行'),
        ('running', '执行中'),
        ('completed', '已完成'),
        ('failed', '失败'),
    ]
    
    name = models.CharField(max_length=200, verbose_name="备份名称")
    backup_type = models.CharField(max_length=20, choices=BACKUP_TYPE_CHOICES, verbose_name="备份类型")
    status = models.CharField(max_length=20, choices=BACKUP_STATUS_CHOICES, default='pending', verbose_name="备份状态")
    
    # 备份信息
    file_path = models.CharField(max_length=500, blank=True, verbose_name="备份文件路径")
    file_size = models.BigIntegerField(blank=True, null=True, verbose_name="文件大小(字节)")
    
    # 时间信息
    started_at = models.DateTimeField(null=True, blank=True, verbose_name="开始时间")
    completed_at = models.DateTimeField(null=True, blank=True, verbose_name="完成时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    
    # 操作信息
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="创建人")
    description = models.TextField(blank=True, verbose_name="备份描述")
    error_message = models.TextField(blank=True, verbose_name="错误信息")
    
    class Meta:
        verbose_name = "数据备份"
        verbose_name_plural = "数据备份"
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.name} - {self.get_status_display()}"
    
    @property
    def duration(self):
        """计算备份耗时"""
        if self.started_at and self.completed_at:
            return self.completed_at - self.started_at
        return None
    
    @property
    def file_size_mb(self):
        """文件大小(MB)"""
        if self.file_size:
            return round(self.file_size / (1024 * 1024), 2)
        return 0


class SystemNotification(models.Model):
    """系统通知模型"""
    NOTIFICATION_TYPE_CHOICES = [
        ('info', '信息'),
        ('warning', '警告'),
        ('error', '错误'),
        ('success', '成功'),
    ]
    
    PRIORITY_CHOICES = [
        ('low', '低'),
        ('medium', '中'),
        ('high', '高'),
        ('urgent', '紧急'),
    ]
    
    title = models.CharField(max_length=200, verbose_name="通知标题")
    message = models.TextField(verbose_name="通知内容")
    notification_type = models.CharField(max_length=20, choices=NOTIFICATION_TYPE_CHOICES, verbose_name="通知类型")
    priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='medium', verbose_name="优先级")
    
    # 接收者
    recipient = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="接收者", related_name='notifications')
    sender = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name="发送者", related_name='sent_notifications')
    
    # 状态信息
    is_read = models.BooleanField(default=False, verbose_name="是否已读")
    read_at = models.DateTimeField(null=True, blank=True, verbose_name="阅读时间")
    
    # 关联信息
    related_url = models.CharField(max_length=500, blank=True, verbose_name="相关链接")
    related_object_type = models.CharField(max_length=50, blank=True, verbose_name="关联对象类型")
    related_object_id = models.PositiveIntegerField(blank=True, null=True, verbose_name="关联对象ID")
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    expires_at = models.DateTimeField(null=True, blank=True, verbose_name="过期时间")
    
    class Meta:
        verbose_name = "系统通知"
        verbose_name_plural = "系统通知"
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['recipient', 'is_read', '-created_at']),
            models.Index(fields=['notification_type', '-created_at']),
        ]
    
    def __str__(self):
        return f"{self.title} - {self.recipient.username}"
    
    def mark_as_read(self):
        """标记为已读"""
        if not self.is_read:
            self.is_read = True
            self.read_at = timezone.now()
            self.save(update_fields=['is_read', 'read_at'])
    
    @classmethod
    def create_notification(cls, recipient, title, message, notification_type='info', priority='medium', sender=None, related_url=None, related_object=None, expires_at=None):
        """创建通知"""
        notification_data = {
            'recipient': recipient,
            'title': title,
            'message': message,
            'notification_type': notification_type,
            'priority': priority,
            'sender': sender,
            'related_url': related_url,
            'expires_at': expires_at,
        }
        
        if related_object:
            notification_data['related_object_type'] = related_object.__class__.__name__
            notification_data['related_object_id'] = related_object.id
        
        return cls.objects.create(**notification_data)
    
    @property
    def is_expired(self):
        """判断是否已过期"""
        if self.expires_at:
            return timezone.now() > self.expires_at
        return False